package org.xx.armory.spring5.jdbc;

import org.springframework.jdbc.core.ResultSetExtractor;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import static org.xx.armory.commons.Validators.rejectIfNonPositive;

public abstract class ScalarMapper<T>
        extends JdbcMapper<T> {
    private final int columnIndex;

    protected ScalarMapper() {
        this(1);
    }

    protected ScalarMapper(
            int columnIndex
    ) {
        this.columnIndex = rejectIfNonPositive(columnIndex, "columnIndex");
    }

    protected final int getColumnIndex() {
        return this.columnIndex;
    }

    protected abstract T extractScalar(
            ResultSet resultSet
    );

    @Override
    public ResultSetExtractor<T> single() {
        return resultSet -> resultSet.next() ? this.extractScalar(resultSet) : null;
    }

    @Override
    public ResultSetExtractor<List<T>> all() {
        return resultSet -> {
            final var result = new ArrayList<T>();

            while (resultSet.next()) {
                result.add(this.extractScalar(resultSet));
            }

            return result;
        };
    }

    @Override
    public ResultSetExtractor<List<T>> page(
            int startRowIndex,
            int maximumRows
    ) {
        return resultSet -> {
            final var result = new ArrayList<T>();

            var row = 0L;
            var more = true;

            // 跳过不需要映射的记录。
            while (row < startRowIndex && (more = resultSet.next())) {
                ++row;
            }

            if (more) {
                row = 0;
                while ((maximumRows == 0 || row < maximumRows) && resultSet.next()) {
                    result.add(this.extractScalar(resultSet));
                    ++row;
                }
            }

            return result;
        };
    }
}
